/*	 
**	 Calculator exercise, lab #1.
**	 Authors: Bruce Blumberg and Doug Keislar, NeXT Technical Support
*/

#import "Calculator.h"
#import <string.h>
#import <math.h>	/* for extensions to existing functionality */	
#import <appkit/Application.h>
#import <appkit/TextField.h>

@implementation Calculator:Object

+new;
{	
	self = [super new];	    /* create new instance of calculator */
	strcpy(viewerStr,"");	    /* initialize string for viewer */
	topOfStack = -1;	    /* initialize stack */
	frozen = NO;
	return self;
}

-(double)pop
{
	if(topOfStack>-1)	 
		return(stack[topOfStack--]);
	else return(0);
}

-push:(double)aNum
{
	if(topOfStack<STACKSIZE-1)
		stack[++topOfStack] = aNum;
	return self;
}

-(double)getOperand
{	
        if (viewerStr[0]) 
		[self enter:self];	/* push displayed value to stack,
					if it hasn't already been done */
	return ([self pop]);
}

-displayValue:(double)aNum
{
	[viewer setFloatValue:aNum]; 	/* display current value */
	strcpy(viewerStr,"");		/* and empty out string for next */
	return self;
}

-pushAndDisplay:(double)aNum
{
	[self push:aNum];
	[self displayValue:aNum];
	return self;
}

-enter:(id)sender
{	
	[self push:[viewer floatValue]];
	strcpy(viewerStr,"");		
	return self;
}

-clearDisplay:(id)sender
{
	if (frozen)  
		frozen = NO;	     
	strcpy(viewerStr,"");
	[self displayValue:0.0];
	return self;
}

-digit:(id)sender
{
	char	digitBuf[2];
			/* get the new digit from the  button's tag and 
			  append it to the displayed string */
	sprintf(digitBuf,"%d",[sender selectedTag]);
			/* we use selectedTag instead of tag, in case the
			button is part of a matrix */	
	strcat(viewerStr,digitBuf);	     		
	[viewer setStringValue:viewerStr];
	return self;
}
	
-period:(id)sender {}		/* EXERCISE: Fill in this method */
	
-add:(id)sender
{	

	if (!frozen) 
		[self pushAndDisplay:[self getOperand]+[self getOperand]];
	return self;
}
			/* EXERCISE: Fill in the following methods */

-subtract:(id)sender {}
-multiply:(id)sender {}
-divide:(id)sender {}
-changeSign:(id)sender {}

-stackError:(STR)errorMsg; {}   /* OPTIONAL EXERCISE: Display error message and  
				reinitialize stack.  Also, all buttons except 
				"clear" should freeze.  Most of the preceding 
				methods will require some modification. */


				/* the following methods are complete
				   and are generated by Interface Builder */
								
- setAWindow:anObject		/* associate the outlet "aWindow" with
				   the user-interface window, "anObject"  */
{
 	 aWindow = anObject;
  	 return self;
}

- setViewer:anObject		/*  initialize the other outlet, viewer  */
{
	  viewer = anObject;
	  return self;
}

@end

